import React from 'react';
import { Button } from 'antd';
import { ErrorResult } from '../ResultPage';
import './style.less';

interface ErrorBoundaryState {
  hasError: boolean;
  error: Error | null;
  errorInfo: React.ErrorInfo | null;
}

interface ErrorBoundaryProps {
  children: React.ReactNode;
  fallback?: React.ReactNode;
  onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
}

class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      errorInfo: null,
    };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    // 更新 state，下次渲染时显示错误界面
    return {
      hasError: true,
      error,
      errorInfo: null,
    };
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    // 可以在这里记录错误日志
    console.error('Error Boundary caught an error:', error, errorInfo);
    
    this.setState({
      error,
      errorInfo,
    });

    // 调用外部错误处理函数
    if (this.props.onError) {
      this.props.onError(error, errorInfo);
    }
  }

  handleRetry = () => {
    // 重置错误状态，尝试重新渲染
    this.setState({
      hasError: false,
      error: null,
      errorInfo: null,
    });
  };

  render() {
    if (this.state.hasError) {
      // 如果提供了自定义的错误展示组件，则使用它
      if (this.props.fallback) {
        return this.props.fallback;
      }

      // 默认的错误展示界面
      return (
        <div className="error-boundary">
          <ErrorResult
            title="页面出错了"
            subTitle={this.state.error?.message || '抱歉，页面渲染过程中发生错误'}
            actions={[
              {
                text: '重试',
                type: 'primary',
                onClick: this.handleRetry,
              },
            ]}
          />
          
          {/* 在开发环境下显示详细错误信息 */}
          {process.env.NODE_ENV === 'development' && this.state.errorInfo && (
            <div className="error-details">
              <h4>错误详情：</h4>
              <pre>{this.state.error?.toString()}</pre>
              <h4>组件堆栈：</h4>
              <pre>{this.state.errorInfo.componentStack}</pre>
            </div>
          )}
        </div>
      );
    }

    return this.props.children;
  }
}

// 创建一个高阶组件，用于包装需要错误边界的组件
export const withErrorBoundary = <P extends object>(
  WrappedComponent: React.ComponentType<P>,
  errorBoundaryProps?: Omit<ErrorBoundaryProps, 'children'>
) => {
  return function WithErrorBoundary(props: P) {
    return (
      <ErrorBoundary {...errorBoundaryProps}>
        <WrappedComponent {...props} />
      </ErrorBoundary>
    );
  };
};

export default ErrorBoundary;